package com.gary;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author peng_rui
 * @date 2022/6/27
 */
public class InterviewStart01 {
    /**
     * HashMap有哪些线程安全的方式：
     *  HashMap不是线程安全的,往往在写程序时需要通过一些方法来回避其实JDK原生的提供了 2种方法让HashMap支持线程安全.
     * 方法一:通过Collections.synchronizedMap(返回一 个新的Map,这个新的map就是线程安全的这个要求大家习惯,基于接口编程,因为返回的并不是HashMap.而是一个Map的实现）
     * 方法二:ConcurrentHashMap.具体的可以查看java.util.concurrent.ConcurrentHashMap.这个方法比方法一有了很大的改进.
     * 方法一特点:
     * 通过Collections.synchronizedMap()来封装所有不安全的HashMap的方法就连toString, hashCode都进行了封装，封装的关键点有2处
     *  1)使用了经典的synchronized来进行互斥，
     *  2)使用了代理模式new了一个新的类这个类同样实现了Map接口.在Hashmap上面,synchronlzed锁住的是对象，所以第一个申请的得到锁，其他线程将进入阻塞等待唤醒.
     * 优点:代码实现十分简单,一看就懂.缺点从锁的角度来看,方法一直接使用了 锁住方法基本上是锁住了尽可能大的代码块:性能会比较差.
     * 方法二特点:
     * ConcurrentHashMap,
     * put():
     *  1.7会进行两次定位，先进行Segment定位再对其内部的Entry数组进行定位，定位后使用自旋锁进行加锁当自旋64次时进行膨胀，膨胀后线程进入阻塞状态，等待唤醒。整个put时都持有锁
     *
     * 1.8只需要进行一次定位，使用synchronized+CAS机制，如对应下标没有节点，说明没有hash碰撞，使用cas进行插入，若成功则返回成功，失败则通过synchronized进行加锁
     *
     * 优点:需要互斥的代码段比较少,性能会比较好. ConcurrentHashMap把整个Map切分成了多个块，发生锁碰撞的几率大大降低，性能会比较好.
     * 缺点:代码繁琐
     *
     *
     *
     *
     */
    public static void main(String[] args) {
        Map<String, Object> map = Collections.synchronizedMap(new HashMap<>());
        ConcurrentHashMap<String, Object> hashMap = new ConcurrentHashMap<>();
    }
}
